package cn.signalpha.modules.shop.controller.seller;

import cn.signalpha.common.constant.AppConstant;
import cn.signalpha.common.constant.MsgConstant;
import cn.signalpha.common.utils.Assert;
import cn.signalpha.core.boot.ctrl.BaseController;
import cn.signalpha.core.cache.utils.CacheUtil;
import cn.signalpha.core.log.exception.ServiceException;
import cn.signalpha.core.mp.support.Condition;
import cn.signalpha.core.secure.TokenUser;
import cn.signalpha.core.tool.api.R;
import cn.signalpha.core.tool.utils.Func;
import cn.signalpha.modules.shop.cache.SellerCacheConstant;
import cn.signalpha.modules.shop.cache.SellerSysCache;
import cn.signalpha.modules.shop.entity.Seller;
import cn.signalpha.modules.shop.entity.SellerRole;
import cn.signalpha.modules.shop.service.SellerRoleService;
import cn.signalpha.modules.shop.service.SellerService;
import cn.signalpha.modules.shop.vo.SellerGrantVO;
import cn.signalpha.modules.shop.vo.SellerRoleVO;
import cn.signalpha.modules.shop.wrapper.SellerRoleWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.*;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 控制器
 *
 * @author signalpha
 */
@RestController
@AllArgsConstructor
@RequestMapping(AppConstant.APPLICATION_SHOP_NAME + "/sys-seller/seller/role")
@Api(value = "商户角色表", tags = "商户角色表")
public class SpiSellerRoleController extends BaseController {

	private final SellerService sellerService;
	private final SellerRoleService sellerRoleService;

	@GetMapping("/list")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "roleName", value = "参数名称", paramType = "query", dataType = "string"),
		@ApiImplicitParam(name = "roleAlias", value = "角色别名", paramType = "query", dataType = "string")
	})
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "列表", notes = "传入role")
	public R<List<SellerRoleVO>> list(@ApiIgnore @RequestParam Map<String, Object> role, TokenUser tokenUser) {
		QueryWrapper<SellerRole> queryWrapper = Condition.getQueryWrapper(role, SellerRole.class);
		queryWrapper.lambda().eq(SellerRole::getSellerId, tokenUser.getTenantId());
		return R.data(SellerRoleWrapper.build().listNodeVO(sellerRoleService.list(queryWrapper)));
	}

	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入role")
	public R<SellerRoleVO> detail(SellerRole sellerRole) {
		SellerRole detail = sellerRoleService.getOne(Condition.getQueryWrapper(sellerRole));
		return R.data(SellerRoleWrapper.build().entityVO(detail));
	}

	@GetMapping("/tree")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "树形结构", notes = "树形结构")
	public R<List<SellerRoleVO>> tree(String sellerId, TokenUser tokenUser) {
		return R.data(sellerRoleService.tree(Long.valueOf(Func.toStrWithEmpty(sellerId, tokenUser.getTenantId()))));
	}

	@GetMapping("/tree-by-id")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "树形结构", notes = "树形结构")
	public R<List<SellerRoleVO>> treeById(Long roleId, TokenUser tokenUser) {
		SellerRole sellerRole = SellerSysCache.getRole(roleId);
		return R.data(sellerRoleService.tree(Func.notNull(sellerRole) ? sellerRole.getSellerId() : Long.valueOf(tokenUser.getTenantId())));
	}

	@PostMapping("/save")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "新增", notes = "传入role")
	public R save(@Valid @RequestBody SellerRole sellerRoleDTO) {
		CacheUtil.clear(SellerCacheConstant.SYS_CACHE, Boolean.FALSE);
		return R.status(sellerRoleService.submit(sellerRoleDTO));
	}

	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入role")
	public R update(@Valid @RequestBody SellerRole sellerRoleDTO) {
		SellerRole sellerRole = sellerRoleService.getById(sellerRoleDTO.getId());
		Assert.isNull(sellerRole, MsgConstant.OBJECT_NULL);
		if(!sellerRole.getRoleAlias().equals(sellerRoleDTO.getRoleAlias())){
			Seller seller = sellerService.getById(sellerRole.getSellerId());
			if(Objects.equals(seller.getRoleId(), String.valueOf(sellerRole.getId()))){
				throw new ServiceException("内置超管角色禁止修改别名");
			}
		}
		CacheUtil.clear(SellerCacheConstant.SYS_CACHE, Boolean.FALSE);
		return R.status(sellerRoleService.submit(sellerRoleDTO));
	}

	@PostMapping("/remove")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		sellerRoleService.listByIds(Func.toLongList(ids)).forEach(sellerRole -> {
			Seller seller = sellerService.getById(sellerRole.getSellerId());
			if(Objects.equals(seller.getRoleId(), String.valueOf(sellerRole.getId()))){
				throw new ServiceException("内置超管角色禁止删除");
			}
		});
		CacheUtil.clear(SellerCacheConstant.SYS_CACHE, Boolean.FALSE);
		return R.status(sellerRoleService.removeRole(ids));
	}

	@PostMapping("/grant")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "权限设置", notes = "传入roleId集合以及menuId集合")
	public R grant(@RequestBody SellerGrantVO sellerGrantVO) {
		CacheUtil.clear(SellerCacheConstant.SYS_CACHE, Boolean.FALSE);
		return R.status(sellerRoleService.grant(sellerGrantVO.getRoleIds(), sellerGrantVO.getMenuIds()));
	}

}
